﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reactive.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;


namespace ViewModels
{
    public static class PropertyContainerExtension
    {
        public static IObservable<ValueChangedEventArgs<TValue>> AsObservable<TValue>(this PropertyContainer<TValue> source)
        {
            return Observable.FromEvent<ValueChangedEventArgs<TValue>>
                (
                    eh => source.EventObject.ValueChanged += (s, e) => eh(e),
                    eh => source.EventObject.ValueChanged -= (s, e) => eh(e)
                );

        }
        public static IDisposable Subscribe<TValue>(this IObservable<TValue> source, PropertyContainer<TValue> container)
        {
            return source.Subscribe(v => container.SetValueAndTryNotify(v));
        }

        private class PropertyContainerObserver<TValue> : IObserver<TValue>
        {

            PropertyContainer<TValue> _container;
            internal PropertyContainerObserver(PropertyContainer<TValue> container)
            {
                _container = container;
            }

            public void OnCompleted()
            {

            }

            public void OnError(Exception error)
            {
                _container.Error = new ErrorEntity { Exception = error, Message = error.Message };
            }

            public void OnNext(TValue value)
            {

            }
        }

    }

    public static class ViewModelExtension
    {

        public static IObservable<PropertyChangedEventArgs> AsObservable(this  ViewModelBase viewModel)
        {
            return Observable.FromEvent<PropertyChangedEventArgs>
                (
                    eh => viewModel.PropertyChanged += (s, e) => eh(e),
                    eh => viewModel.PropertyChanged -= (s, e) => eh(e)
                );

        }

        public static IObservable<PropertyChangedEventArgs> AsObservable<TViewModel,TProperty>(this  TViewModel viewModel ,Expression<Func<TViewModel,TProperty>> expression   ) where TViewModel:ViewModelBase<TViewModel>
        {
            var eventObj = viewModel.GetPropertyValueChangeEventObject(expression);

          return   Observable.FromEvent<PropertyChangedEventArgs>
                (
                    eh => eventObj.ValueChanged  += (s, e) => eh(e),
                    eh => eventObj.ValueChanged -= (s, e) => eh(e)
                );

        }

    }





}
